package com.project.personalfundmanager.client;

import java.util.Arrays;
import java.util.List;

import com.extjs.gxt.ui.client.Style.LayoutRegion;
import com.extjs.gxt.ui.client.Style.SelectionMode;
import com.extjs.gxt.ui.client.data.BaseModel;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.ComponentEvent;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.MenuEvent;
import com.extjs.gxt.ui.client.event.MessageBoxEvent;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.store.TreeStore;
import com.extjs.gxt.ui.client.util.Margins;
import com.extjs.gxt.ui.client.widget.Component;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.button.ButtonBar;
import com.extjs.gxt.ui.client.widget.layout.BorderLayout;
import com.extjs.gxt.ui.client.widget.layout.BorderLayoutData;
import com.extjs.gxt.ui.client.widget.menu.Menu;
import com.extjs.gxt.ui.client.widget.menu.MenuBar;
import com.extjs.gxt.ui.client.widget.menu.MenuBarItem;
import com.extjs.gxt.ui.client.widget.menu.MenuItem;
import com.extjs.gxt.ui.client.widget.treepanel.TreePanel;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.resources.client.impl.ImageResourcePrototype;
import com.google.gwt.user.client.ui.AbstractImagePrototype;
import com.project.personalfundmanager.client.common.GlobalRegister;
import com.project.personalfundmanager.client.common.ModelHelper;
import com.project.personalfundmanager.client.facebook.Callback;
import com.project.personalfundmanager.client.facebook.FacebookHelper;
import com.project.personalfundmanager.client.facebook.JSOModel;
import com.project.personalfundmanager.client.facebook.JSOReadyListener;
import com.project.personalfundmanager.client.listeners.Displayable;
import com.project.personalfundmanager.client.listeners.TaxInputListener;
import com.project.personalfundmanager.client.taxitems.ParentItem;
import com.project.personalfundmanager.shared.models.TaxInfoGroupModel;

@SuppressWarnings( "unchecked" )
public class TaxInputPanel extends ContentPanel
{
	TaxInfoGroupModel taxGroupModel;
	List<ParentItem> items;
	private TaxInputListener listener;
	private TreePanel<BaseModel> treePanel;
	private ContentPanel centerPanel;
	public final int DEV_ID = 11111;

	public TaxInputPanel( TaxInputListener listener )
	{
		initModel();
		this.listener = listener;
		setHeading( "Tax Management" );
		setLayout( new BorderLayout() );
		setBorders( true );
		setHeight( 460 );

		BorderLayoutData westData = new BorderLayoutData( LayoutRegion.WEST, 200, 150, 250 );
		westData.setMargins( new Margins( 5, 0, 5, 5 ) );
		westData.setCollapsible( true );

		BorderLayoutData centerData = new BorderLayoutData( LayoutRegion.CENTER );
		centerData.setMargins( new Margins( 5 ) );

		setTopComponent( getMainToolbar() );
		add( getTreePanel(), westData );
		add( getCenterPanel(), centerData );

		selectFirstItem();
		GlobalRegister.setPanelItems( items );
		GlobalRegister.setTaxGroupModel( taxGroupModel );
	}

	private void initModel()
	{
		if ( GlobalRegister.getTaxGroupModel() == null )
			taxGroupModel = new TaxInfoGroupModel();
		else
			taxGroupModel = GlobalRegister.getTaxGroupModel();
		
		items = ModelHelper.getModelWrappers( taxGroupModel );
	}

	private Component getMainToolbar()
	{
		Menu fileMenu = new Menu();
		MenuItem saveMenuItem = new MenuItem( "Save", new SelectionListener<MenuEvent>()
		{
			public void componentSelected( MenuEvent ce )
			{
				FacebookHelper.getUserModel( new JSOReadyListener()
				{
					public void onJSOReady( JSOModel model )
					{
						
						if ( GWT.isProdMode() )
							taxGroupModel.setUid( Long.parseLong( model.get( "id" ) ) );
						else
						{
							taxGroupModel.setUid( DEV_ID );
						}

						GreetingServiceAsync async = ( GreetingServiceAsync ) GWT.create( GreetingService.class );
						async.saveObject( taxGroupModel, new Callback<Boolean>()
						{
							public void onSuccess( Boolean result )
							{
								MessageBox.info( "Status!", "Object is " + ( result ? "" : "not " ) + "saved succesessfully", null );
							}
						} );
					}
				} );
			}
		} );

		MenuItem loadMenuItem = new MenuItem( "Load", new SelectionListener<MenuEvent>()
		{
			public void componentSelected( MenuEvent ce )
			{
				FacebookHelper.getUserModel( new JSOReadyListener()
				{
					public void onJSOReady( JSOModel model )
					{
						long uid;
						if ( GWT.isProdMode() )
							uid = Long.parseLong( model.get( "id" ) );
						else
							uid = DEV_ID;

						GreetingServiceAsync async = ( GreetingServiceAsync ) GWT.create( GreetingService.class );
						async.getObject( uid, new Callback<TaxInfoGroupModel>()
						{
							public void onSuccess( TaxInfoGroupModel model )
							{
								TaxInfoGroupModel.copyToModel( model, taxGroupModel );
							}
						} );
					}
				} );
			}
		} );
		
		MenuItem logoutMenuItem = new MenuItem( "Logout", new SelectionListener<MenuEvent>()
				{
					public void componentSelected( MenuEvent ce )
					{
						GlobalRegister.getFbCore().logout(new Callback<JavaScriptObject>(){
							public void onSuccess(JavaScriptObject result) 
							{
								MessageBox.info("FBCore", "You have logged out successfully", null);
							};
						});
					}
				} );


		saveMenuItem.setIcon( AbstractImagePrototype.create( new ImageResourcePrototype( "save", "/personalfundmanager/resources/local/save_icon.png", 0, 0, 16, 16, false, false ) ) );
		loadMenuItem.setIcon( AbstractImagePrototype.create( new ImageResourcePrototype( "load", "/personalfundmanager/resources/local/load_icon.gif", 0, 0, 16, 16, true, false ) ) );
		logoutMenuItem.setIcon(AbstractImagePrototype.create( new ImageResourcePrototype( "load", "/personalfundmanager/resources/local/icon-logout-small.png", 0, 0, 16, 16, true, false ) ) );
		
		fileMenu.add(saveMenuItem);
		fileMenu.add(loadMenuItem);
		fileMenu.add(logoutMenuItem);

		MenuBar menuBar = new MenuBar();
		menuBar.add( new MenuBarItem( "File", fileMenu ) );
		return menuBar;
	}

	private ContentPanel getCenterPanel()
	{
		centerPanel = new ContentPanel();
		ButtonBar buttonBar = getActionBar();
		centerPanel.setBottomComponent( buttonBar );
		return centerPanel;
	}

	private ContentPanel getTreePanel()
	{
		ContentPanel panel1 = new ContentPanel();
		panel1.setHeading( "Tax Items" );
		TreeStore<BaseModel> store = geTreeStore();
		treePanel = new TreePanel<BaseModel>( store );
		treePanel.getSelectionModel().setSelectionMode( SelectionMode.SINGLE );
		treePanel.setDisplayProperty( "displayString" );
		treePanel.expandAll();
		treePanel.addListener( Events.OnClick, new Listener<ComponentEvent>()
		{
			public void handleEvent( ComponentEvent be )
			{
				BaseModel model = treePanel.getSelectionModel().getSelectedItem();
				loadSelectedItem( model );
			}
		} );
		panel1.add( treePanel );
		return panel1;
	}

	private void selectFirstItem()
	{
		treePanel.getSelectionModel().setSelection( Arrays.asList( new BaseModel[]
		{ taxGroupModel.getTaxableIncome() } ) );
		loadSelectedItem( taxGroupModel.getTaxableIncome() );
	}

	private void loadSelectedItem( BaseModel model )
	{
		if ( model == null )
			return;

		String selectedValue = model.get( "displayString" );
		for ( ParentItem item : items )
		{
			if ( item.model == model )
			{
				centerPanel.removeAll();
				centerPanel.add( item );
				centerPanel.setHeading( selectedValue );
				centerPanel.layout( true );
			}
		}
	}

	private TreeStore<BaseModel> geTreeStore()
	{
		TreeStore<BaseModel> models = new TreeStore<BaseModel>();
		models.add( ModelHelper.getAllInputModels( taxGroupModel ), true );
		return models;
	}

	private ButtonBar getActionBar()
	{
		ButtonBar buttonBar = new ButtonBar();
		buttonBar.setStyleAttribute( "marginTop", "5px" );
		buttonBar.setStyleAttribute( "marginBottom", "5px" );
		buttonBar.setStyleAttribute( "marginLeft", "10px" );
		buttonBar.setSpacing( 10 );
		buttonBar.add( new Button( "Calculate Tax", new SelectionListener<ButtonEvent>()
		{
			public void componentSelected( ButtonEvent ce )
			{
				listener.actionPerformed();
			}
		} ) );

		buttonBar.add( new Button( "Clear", new SelectionListener<ButtonEvent>()
		{
			public void componentSelected( ButtonEvent ce )
			{
				for ( ParentItem item : GlobalRegister.getPanelItems() )
				{
					if ( item.model == treePanel.getSelectionModel().getSelectedItem() )
					{
						item.clearItems();
						break;
					}
				}
				( ( Displayable ) treePanel.getSelectionModel().getSelectedItem() ).setDisplayString();
			}
		} ) );

		buttonBar.add( new Button( "Clear All", new SelectionListener<ButtonEvent>()
		{
			public void componentSelected( ButtonEvent ce )
			{
				MessageBox.confirm( "Are you sure?", "This action will clear all information, you entered. \nDo you really want to do that ?", new Listener<MessageBoxEvent>()
				{
					public void handleEvent( MessageBoxEvent be )
					{
						if ( be.getButtonClicked() != null && be.getButtonClicked().getText().equals( "Yes" ) )
						{
							for ( ParentItem tabItem : items )
							{
								tabItem.clearItems();
								( ( Displayable ) tabItem.model ).setDisplayString();
							}

						}
					}
				} );
			}
		} ) );
		return buttonBar;
	}
}
